<template>
    <div class="file-upload">
        <div class="file-upload-container" v-bind="$attrs" @click="triggerUpload">
            <slot name="loading" v-if="fileStatus == 'loading'">
                <button class="btn btn-primary">正在上传...</button>
            </slot>
            <slot v-else>
                <button class="btn btn-primary">点击上传</button>
            </slot>
            <slot name="success" v-if="fileStatus == 'success'" :uploadedData="uploadedData">
                <button class="btn btn-primary">上传成功</button>
            </slot>
        </div>
        <input type="file" class="file-input d-none" ref="fileInput" @change="handleFileChange" />
    </div>
</template>

<script lang="ts">
import { defineComponent, ref, PropType } from "vue";
import createMessage from "@/components/createMessage";
import { uploadFile } from "@/api/column";
import { ResponseProps } from "@/utils/request";
type UploadStatus = "ready" | "loading" | "success" | "error";
type BeforeUploadFun = (file: File) => boolean;
export default defineComponent({
    props: {
        beforeUpload: {
            type: Function as PropType<BeforeUploadFun>,
        },
        actiionApi: {
            type: Function as PropType<(data: object | null) => Promise<ResponseProps>>,
            default: uploadFile,
        },
    },
    inheritAttrs: false,
    emits: ["file-uploaded", "file-upload-error"],
    setup(props, context) {
        const fileInput = ref<null | HTMLInputElement>(null);
        const fileStatus = ref<UploadStatus>("ready");
        const triggerUpload = () => {
            if (fileInput.value) {
                fileInput.value.click();
            }
        };
        const uploadedData = ref(null);
        const handleFileChange = (e: Event) => {
            const target = e.target as HTMLInputElement;
            let file = target.files[0];
            if (props.beforeUpload) {
                if (!props.beforeUpload(file)) {
                    return;
                }
            }
            fileStatus.value = "loading";
            let formData = new FormData();
            formData.append("file", file);
            props
                .actiionApi(formData)
                .then(res => {
                    if (res.code === 0) {
                        uploadedData.value = res.data;
                        context.emit("file-uploaded", res.data);
                        createMessage("上传成功", "success");
                        fileStatus.value = "success";
                    } else {
                        context.emit("file-upload-error", res.data);
                        createMessage("上传失败", "error");
                        fileStatus.value = "error";
                    }
                })
                .catch(err => {
                    context.emit("file-upload-error", err);
                    fileStatus.value = "error";
                })
                .finally(() => {
                    fileInput.value.value = "";
                });
        };
        return { fileInput, triggerUpload, handleFileChange, fileStatus, uploadedData };
    },
});
</script>

<style scoped lang="scss"></style>
